package com.hrms.hrms_security.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hrms.common.utils.JwtUtils;
import com.hrms.common.vo.ResultMessage;
import com.hrms.hrms_security.component.PasswordEncoder2;
import com.hrms.hrms_security.constant.RsaProperties;
import com.hrms.hrms_security.dao.SysUsrDao;
import com.hrms.hrms_security.entity.SysUsr;
import com.hrms.hrms_security.exception.BusinessException;
import com.hrms.hrms_security.service.SysUsrService;
import com.hrms.common.utils.RSAUtils;
import com.hrms.common.utils.RedisUtil;

import com.hrms.hrms_security.vo.AccountUser;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;

/**
 * (SysUsr)表服务实现类
 *
 * @author makejava
 * @since 2024-03-28 14:07:49
 */
@Service("sysUsrService")
public class SysUsrServiceImpl extends ServiceImpl<SysUsrDao, SysUsr> implements SysUsrService {


    @Resource
    AuthenticationManager authenticationManager;

    @Resource
    RedisUtil redisUtil;
    @Resource
    PasswordEncoder2 passwordEncoder2;
    @Resource
    private SysUsrDao sysUsrDao;
    @Override
    public ResultMessage usrLogin(SysUsr sysUsr) {
        //1.封装Authentication对象
        UsernamePasswordAuthenticationToken authenticationToken =
                new UsernamePasswordAuthenticationToken(sysUsr.getSysUsrName(), sysUsr.getSysUsrPassword());

        //2.通过AuthenticationManager的authenticate方法来进行用户认证
        Authentication authenticated = authenticationManager.authenticate(authenticationToken);

        //3.在Authentication中获取用户信息
        AccountUser loginUser = (AccountUser) authenticated.getPrincipal();
        String username = loginUser.getUsername();
        //4.认证通过生成token
        String jwt = JwtUtils.createJWT(username);
        //6.把token返回给前端
        HashMap<Object, Object> hashMap = new HashMap<>();
        hashMap.put("token", jwt);
        redisUtil.setEntity("login."+username, loginUser);
        return new ResultMessage(ResultMessage.Success,"成功",hashMap);
    }

    @Override
    public SysUsr getByUsername(String username) {
        LambdaQueryWrapper<SysUsr> queryWrapper = new LambdaQueryWrapper<SysUsr>().eq(SysUsr::getSysUsrName, username);
        SysUsr sysUsr = this.getOne(queryWrapper);
        if (sysUsr == null) {
            throw new UsernameNotFoundException("用户名或密码错误");
        }
        return sysUsr;
    }

    @Override
    public String getUserAuthorityInfo(Long userId) {
        List<String> authority = sysUsrDao.getUserAuthorityInfo(userId);
        return StringUtils.join(authority,",");
    }

    @Override
    public ResultMessage usrRegister(SysUsr sysUsr) throws BusinessException {
        try {
            initValidate(sysUsr);
            //RSA解密
            String pwd = RSAUtils.decryptByPrivate(sysUsr.getSysUsrPassword(), RsaProperties.privateKey);
            //SpringSecurity 密码编码
            String encodePwd = passwordEncoder2.encode(pwd);
            sysUsr.setSysUsrPassword(encodePwd);
            sysUsr.setCreatedBy(sysUsr.getSysUsrName());
            this.save(sysUsr);
            this.sysUsrDao.saveDetails(sysUsr.getId());
        }catch (Exception e) {
            return new ResultMessage(ResultMessage.Error,"注册失败");
        }
        return new ResultMessage(ResultMessage.Success,"注册成功");
    }

    @Override
    public SysUsr getByAccount(String sysUsrName) throws BusinessException {
        return this.getOne(new LambdaQueryWrapper<SysUsr>().eq(SysUsr::getSysUsrName, sysUsrName));
    }

    @Override
    public ResultMessage loginOut() {
        UsernamePasswordAuthenticationToken authentication = (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
        AccountUser LoginUser = (AccountUser) authentication.getPrincipal();
        redisUtil.delete("login." + LoginUser.getUsername());
        return new ResultMessage(ResultMessage.Success,"退出登录成功！");
    }

    private void initValidate(SysUsr sysUsr) throws  BusinessException {
        if (sysUsr.getSysUsrName() == null) {
            throw new BusinessException("用户名不能为空");
        }
        else if (sysUsr.getSysUsrPassword() == null) {
            throw new BusinessException("密码不能为空");
        }
        int count = this.count(new LambdaQueryWrapper<SysUsr>().eq(SysUsr::getSysUsrName, sysUsr.getSysUsrName()));
        if (count > 0 ) {
            throw new BusinessException("用户名重复 ,请重新选择用户名");
        }
    }
}

